﻿package com.everydayflash.pv3d.blender {
	
	import com.everydayflash.pv3d.BlogLink;
	import com.everydayflash.pv3d.modifiers.Bend;
	import com.everydayflash.pv3d.TopBar;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.filters.BlurFilter;
	import flash.filters.GlowFilter;
	import flash.filters.GradientBevelFilter;
	import flash.filters.GradientGlowFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import org.papervision3d.materials.shadematerials.GouraudMaterial;
	
	import org.papervision3d.core.proto.MaterialObject3D;
	import org.papervision3d.materials.shadematerials.CellMaterial;
	import org.papervision3d.materials.shadematerials.EnvMapMaterial;
	import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
	import org.papervision3d.materials.shadematerials.PhongMaterial;
	import org.papervision3d.materials.WireframeMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.events.FileLoadEvent;
	import org.papervision3d.objects.parsers.KMZ;
	import org.papervision3d.view.BasicView;
	
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.display.StageAlign;
	
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.core.proto.LightObject3D;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	/**
	* @author Bartek Drozdz / www.everydayflash.com
	*/
	public class LadyDae extends BasicView {
		
		private var daeFile:String = "woman";
		private var gchild:String = "LadyDae";
		
		private var kmz:KMZ;
		private var daeDo3d:DisplayObject3D;
		
		private var bend:Bend;
		private var bendAngle:Number = 0;
		
		private var materials:Array;
		private var materialIndex:int = 0;
		
		private var topBar:TopBar;
		private var blogLink:BlogLink;
		
		[Embed(source = 'pattern.gif')]
		private var Pattern:Class;
		private var pattern:Sprite;
		
		private var light:LightObject3D;
		
		private var mouseDown:Boolean = false;
		private var currentRotationX:Number = 0;
		private var currentRotationY:Number = 0;
		private var mouseClickX:Number = 0;
		private var mouseClickY:Number = 0;
		
		[Embed(source = 'nyc.jpg')]
		private var Environment:Class;
		
		private var instr:String = "Hit SPACE to change material, click and drag for manual rotation";
		private var styles:Array = ["<b>Lady Dae</b>", 
									"<b>Lawnmower Lady</b>", 
									"<b>The Lady from Goldfinger</b>", 
									"<b>The Mighty Lady Hulk</b>", 
									"<b>Lady T-1000</b>"];
										  
		private var filterSets:Array = [[],
										[new GlowFilter(0x2aafcc, .8, 4, 4, 3, 1)],
										[new GlowFilter(0xfff888, .5, 20, 20, 3, 1)],
										[],
										[]];
		
		public function LadyDae() {

			stage.quality = StageQuality.MEDIUM;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			super(640, 480, true);
			
			camera.zoom = 5; 
			camera.focus = 200;
			
			pattern = new Sprite();
			addChildAt(pattern, 0);
			
			topBar = new TopBar("Loading...", true);
			addChild(topBar);
			topBar.overrideLink(instr);
			
			blogLink = new BlogLink();
			addChild(blogLink);
			
			onResize();
			
			light = new PointLight3D(false, false);
			light.z = -600;
			light.y = 200;
			light.x = -300;
			scene.addChild(light);
			
			kmz = new KMZ();
			kmz.addEventListener(FileLoadEvent.LOAD_COMPLETE, onKmz);
			kmz.addEventListener(FileLoadEvent.LOAD_ERROR, onKmzError);
			kmz.load("dae/" + daeFile + ".zip");

			stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, animate);
			stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
			stage.addEventListener(MouseEvent.MOUSE_WHEEL, onWheel);
			stage.addEventListener(Event.RESIZE, onResize);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, swapMaterial);
		}

		private function onKmz(e:Event = null):void {
			kmz.dae.scale = 10;
			scene.addChild(kmz);
			prepareDae();
		}
		
		private function onKmzError(e:FileLoadEvent):void {
			trace("onKmzError" + e);
		}

		private function prepareDae():void {	
			// For my blog raders: this it THE MOST important line
			daeDo3d = kmz.dae.getChildByName("COLLADA_Scene").getChildByName(gchild);
			
			materials = new Array();
			materials.push(new WireframeMaterial(0xffffff, .8, 0));
			materials.push(new FlatShadeMaterial(light, 0xff0000, 0x191919));
			materials.push(new CellMaterial(light, 0xfff888, 0xe5cd04, 8));
			materials.push(new PhongMaterial(light, 0x12e212, 0x105007, 20));

			var envBlur:BitmapData = (new Environment() as Bitmap).bitmapData
			envBlur.applyFilter(envBlur, envBlur.rect, new Point(), new BlurFilter(5, 5, 3));
			materials.push(new EnvMapMaterial(light, envBlur));
			
			swapMaterial();
			
			kmz.rotationY = 90;
			bend = new Bend(daeDo3d);
			
			startRendering();
		}
		
		private function swapMaterial(ke:KeyboardEvent = null):void {
			daeDo3d.material = materials[materialIndex];
			topBar.update(styles[materialIndex]);
			viewport.filters = filterSets[materialIndex];
			viewport.cacheAsBitmap = true;
			
			materialIndex++;
			if (materialIndex == materials.length) materialIndex = 0;
		}
		
		private function onResize(e:Event=null):void {
			topBar.resize();
			blogLink.resize();
			pattern.graphics.beginBitmapFill((new Pattern() as Bitmap).bitmapData, null, true);
			pattern.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			pattern.graphics.endFill();
		}
		
		private function onDown(me:MouseEvent):void {
			mouseDown = true;
			currentRotationX = kmz.rotationX;
			currentRotationY = kmz.rotationY;
			mouseClickX = me.stageX;
			mouseClickY = me.stageY;
		}
		
		private function animate(me:MouseEvent):void {
			if (mouseDown) {
				var r:Number = (mouseClickX - me.stageX) / stage.stageWidth;
				kmz.rotationY = currentRotationY + r * -270;
				
				r = (mouseClickY - me.stageY) / stage.stageHeight;
				kmz.rotationX = currentRotationX + r * -270;
			} else {
				bendToMouse()
			}
		}
		
		private function onUp(me:MouseEvent):void {
			mouseDown = false;
			bendToMouse();
		}
		
		private function onWheel(me:MouseEvent):void {
			camera.z = Math.min( -200, camera.z + me.delta * 3);
			camera.z = Math.max( -2000, camera.z + me.delta * 3);
		}
		
		private function bendToMouse():void {
			bendAngle = (stage.mouseX / stage.stageWidth * 2) - 1;
			var a:Number = Math.sin(bendAngle);
			if (a > 0) bend.constraint = Bend.LEFT;
			else bend.constraint = Bend.NONE;
			bend.quickBend(a * 1.5, .5);
		}
		
		override protected function onRenderTick(event:Event = null):void {
			super.onRenderTick(event);
			if (!mouseDown) {
				kmz.rotationY += 2;
				//kmz.rotationX += 1;
			}
		}
	}
	
}